﻿namespace TPXSDK.NET.Link;

/// <summary>
/// 遥测报文类型编码定义
/// </summary>
public enum TlmType
{
    STD0    = 0x00,
    STD1    = 0x01,
    STD2    = 0x02,
    STD3    = 0x03,
    STD4    = 0x04,

    USR0    = 0x05,
    USR1    = 0x06,
    USR2    = 0x07,
    USR3    = 0x08,
    USR4    = 0x09,

    TXT     = 0x0B,
    CODE    = 0x0C,

    BCST    = 0x20,
    GIMBAL  = 0x21,
    OBST    = 0x22
}

/// <summary>
/// 通用帧头数据内容 （不含前导码 2Byte）
/// </summary>
public class FrameHeader
{
    public byte PayloadLen; // 负载字段长度
    public byte SrcAddr;    // 帧源地址
    public byte DstAddr;    // 帧目的地址
    public byte Sn;         // 帧序列号
}

/// <summary>
/// 飞行状态定义
/// </summary>
public enum FlightStage
{
    IDLE,   // 空闲状态
    TAKEOFF,// 自主起飞
    WPNAV,  // 航点模式
    CIRCLE, // 盘旋模式
    GUIDED, // 引导模式
    RTL,    // 返航模式
    LAND,   // 降落模式
    TRANS,  // 转换模式
    HOVER,  // 悬停模式
}

/// <summary>
/// 报文命令码字定义
/// </summary>
public enum LinkCmd
{
    MISSION_EDIT    = 0x10, // Modify Mission Info
    MISSION_QUERY   = 0x11, // Query Mission  data
    RCIN_UPDATE     = 0x20, // Update radio control data
    SERVO_OUT       = 0x21, // Set servo out data
    JOYSTICK_UPDATE = 0x22, // Update joystick control data
    FOLLOW_TARGET   = 0x23, // Update Follow target information
    HEART_BEAT      = 0x30, // Heart beat for device  report

    RTCM_UPDATE     = 0x32, // Send RTCM data to GNSS Receiver
    SET_FLIGHT_MODE = 0x40, // Set flight mode
    DO_ACTION       = 0x41, // Do action by parameters
    ENTER_IAP       = 0xB1, // Set device to IAP mode
    ERASE_FLASH     = 0xB2, // Set device to erase flash
    DOWNLOAD_BIN    = 0xB3, // Set device to download firmware
    ENTER_UDISK     = 0xB4, // Set device to U-Disk mode
    SAVE_SETTING    = 0xCC, // Save setting data to flash
    SAVE_SETTING_FILE = 0xCD, // Save setting data to file
    READ_LOG_DATA   = 0xD0, // Read log data
    READ_LOG_META   = 0xD1, // Read log meta info
    READ_UOBJ_META  = 0xE0, // Read UAV Object meta data

    GET_FIELD_STR   = 0xE1, // Get field value by field name
    SET_FIELD_STR   = 0xE2, // Set field value by field name
    SET_SAVE_FIELD_STR = 0xE3, // Set&save field by field name

    GET_FIELD       = 0xF0, // Get field value by ID
    SET_FIELD       = 0xF1, // Set field value with response
    SET_SAVE_FIELD  = 0xF2, // Set and save field with response

    ZPACK_UPDATE    = 0xF3, // Send ZPACK data for HIL model
    OFFBOARD_REQ    = 0xF4  // Command request from offboard
};

/// <summary>
/// DoAction操作子命令编码
/// </summary>
public enum ActionSubCmd
{
    TAKEOFF         = 0xA0,
    JUMP            = 0xA1,
    AUTH            = 0xA2,
    GUIDE           = 0xA3,
    TEST            = 0xA4,
    SET_FAKEGPS     = 0xA5,
    SET_HILMODE     = 0xA6,
    CALIB           = 0xA7,
    SET_ADDR        = 0xA8,
    FORMATION       = 0xA9,
    WARHEAD         = 0xAA,
    POD_CTRL        = 0xAB,
    TRACE_OBJ       = 0xAC,
    TAG_MSG         = 0xAD,
    LAND            = 0xAE,
    HOVER           = 0xAF,
    LIGHT           = 0xB0,
    CHUTE           = 0xB1, // 降落伞控制指令
    RTL             = 0xB2, // 指点返航控制指令
    IOCTRL          = 0xB3, // GPIO 控制指令
    PWMCTRL         = 0xB3, // PWM 控制指令
}

public enum CalibParam
{
    CALIB_PARAM_MAG = 0x00,
    CALIB_PARAM_ESC = 0x01,
    CALIB_PARAM_ACC = 0x02,
}

/// <summary>
/// Log操作子命令编码
/// </summary>
public enum LogSubCmd
{
    READ_POS_DATA   = 0xFC,
    READ_POS_META   = 0xFD,
    READ_BIN_DATA   = 0xFE,
    READ_BIN_META   = 0xFF,
}

/// <summary>
/// Mission操作子命令编码
/// </summary>
public enum MisSubCmd
{
   FLY_ADMIN        = 0x00,
   FLY_ITEM         = 0x02,
   MIS_UPDATE       = 0x03
}

/// <summary>
/// Joystick操作子命令编码
/// </summary>
public enum JoySubCmd
{
    BTNS            = 0x00,
    AXIS            = 0x01
}

/// <summary>
/// PodCtrl操作子命令编码
/// </summary>
public enum PodSubCmd
{
    SNAP            = 0x00,
    ZOOM_SET        = 0x01, // 指定倍率缩放
    ANGLE           = 0x02,
    RECORD          = 0x03,
    LIDAR           = 0x04,
    OSD             = 0x05,
    MOVE            = 0x06,
    VIDEOSRC        = 0x07,
    TRACE           = 0x08,
    SETADDR         = 0x09, // 设置吊舱IP地址
    GETADDR         = 0x0A, // 读取吊舱IP地址
    TRACE_OBJ       = 0x0B, // 跟踪指定对象ID
    ZOOM_IN         = 0x0C, // 连续放大
    ZOOM_OUT        = 0x0D, // 连续缩小
    ZOOM_STOP       = 0x0E, // 停止变倍

}

/// <summary>
/// 吊舱移动指令参数编码
/// </summary>
public enum PodMoveCode
{
    MOVE_STOP  = 0x00, // 停止
    MOVE_UP    = 0x01, // 上移
    MOVE_DOWN  = 0x02, // 下移
    MOVE_LEFT  = 0x03, // 左移
    MOVE_RIGHT = 0x04, // 右移
    MOVE_ZERO  = 0xFF, // 归中
}


public enum UObjMetaSubCmd
{
    SIG             = 0x00, // 读取UObject模板签名
    CLS             = 0x01, // 读取UObject类元信息
    MEM             = 0x02  // 读取UObject成员元信息
}

/// <summary>
/// 失效模式标志位
/// </summary>
public enum FailureBit
{
    CTRL    = 0,
    FATAL   = 1,
    GPS     = 2,
    ENGINE  = 3,
    BATTERY = 4,
    RC      = 5,
    GCS     = 6,
    FENCE   = 7
}

/// <summary>
/// 遥控器状态编码
/// </summary>
public enum RCState
{
    OK          = 0,
    LOST_SIG    = 1,
    FAIL_SAFE   = 2,
    DIS_CNNT    = 3
}

/// <summary>
/// TPLink 通信协议相关定义
/// </summary>
public static class LinkDef
{
    public const int MinPkSize = 8;     // 最小帧长度
    public const int MaxPkSize = 128;   // 最大帧长度
    public const byte Header1 = 0xA5;   // 帧起始符号1
    public const byte Header2 = 0x5A;   // 帧起始符号2
    public const int FlyCmdItemSize = 12;

    /// <summary>
    /// 用于判读是否存在指定失效模式
    /// </summary>
    public static bool HasFailure(uint flag, FailureBit bit)
    {
        return (flag & 1 << (int)bit) != 0;
    }

    /// <summary>
    /// 将RC状态字转换为字符串(英文)
    /// </summary>
    public static string RCState2Str(byte rcState)
    {
        return rcState switch
        {
            0 => "RC OK",
            1 => "RC LS",
            2 => "RC FS",
            3 => "RC NO",
            _ => "RC ??"
        };
    }

    /// <summary>
    /// 将RC状态字转换为字符串(中文)
    /// </summary>
    public static string RCState2Str2(byte rcState)
    {
        return rcState switch
        {
            0 => "RC正常",
            1 => "RC丢帧",
            2 => "RC关机",
            3 => "RC断联",
            _ => "RC未知?"
        };
    }

    /// <summary>
    /// 将GPS状态字转换为字符串
    /// </summary>
    public static string GPSState2Str(byte gpsState)
    {
        return gpsState switch
        {
            0 => "NOGPS",
            1 => "NOFIX",
            2 => "2DFIX",
            3 => "3DFIX",
            4 => "DGPS",
            5 => "RTK_F",
            6 => "RTK",
            7 => "FAKE",
            8 => "HIL",
            _ => "GNSS?"
        };
    }
}
